package com.ytf.auth.authentication;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

/**
 * @className: SmsAuthenticationFilter
 * @author: YTF
 * @date: 2025/5/1 9:33
 * @description: 验证码过滤器
 */
//@Component
public class SmsAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/login/sms",
            "POST");

    public SmsAuthenticationFilter() {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER);
    }

    public SmsAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        if ( !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        String phone = request.getParameter("phone");
        String smsCode = request.getParameter("smsCode");
        SmsAuthenticationToken authRequest = SmsAuthenticationToken.unauthenticated(phone,smsCode);
        authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
        // 注意ProviderManager.authenticate 方法 通过该方法查找对应的Provider.supports
        Authentication authentication = this.getAuthenticationManager().authenticate(authRequest);
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authentication);
        SecurityContextHolder.setContext(context);

        // 显式存储到 Session（关键！）
        new HttpSessionSecurityContextRepository().saveContext(context, request, response);

        return authentication;
    }

}
